package cn.zh.word.utils;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.ChartMultiSeriesRenderData;
import com.deepoove.poi.data.SeriesRenderData;
import com.deepoove.poi.util.PoitlIOUtils;
import org.springframework.lang.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zh
 */
public class GenerateWordUtils {

    /**
     * 初始化模板配置
     */
    public static Configure initConfig(){
        return Configure.builder()
                // 对未找到标签做清空处理
                .setValidErrorHandler(new Configure.DiscardHandler())
                .build();
    }

    /**
     * 编译模板
     * @param file 模板文件
     * @param configure 模板配置
     */
    public static XWPFTemplate compileTemplate(File file, Configure configure){
       return XWPFTemplate.compile(file, configure);
    }

    /**
     * 生成图表数据
     * @param title 图表标题
     * @param xData 图表x轴数据
     * @param yDataMap 图表y轴数据，k:分类名称 v:x轴对应y轴数据
     * @return 图表数据类
     */
    public static ChartMultiSeriesRenderData generateCharData(String title,
                                                     List<String> xData,
                                                     HashMap<String, List<? extends Number>> yDataMap){
        ChartMultiSeriesRenderData multiData = new ChartMultiSeriesRenderData();
        // 标题
        multiData.setChartTitle(title);
        // x轴数据
        multiData.setCategories(xData.toArray(new String[xData.size()]));
        // y轴数据
        List<SeriesRenderData> seriesList = new ArrayList<>(yDataMap.size());
        yDataMap.forEach((k,v) -> {
            seriesList.add(new SeriesRenderData(k,v.toArray(new Number[v.size()])));
        });
        multiData.setSeriesDatas(seriesList);
        return multiData;
    }

    /**
     * 填充数据
     * @param template 模板类
     * @param map 数据Map k:模板对应key v:数据类
     */
    public static void fillData(XWPFTemplate template, Map<String, Object> map){
        template.render(map);
    }

    /**
     * 输出 word
     * @param template 模板类
     * @param out 输出流
     * @throws IOException
     */
    public static void outputWord(XWPFTemplate template, OutputStream out) throws IOException {
        template.write(out);
        PoitlIOUtils.closeQuietlyMulti(template, out);
    }

    /**
     * 生成 word
     * @param file 模板文件
     * @param configure 模板配置
     * @param dataMap 数据Map
     * @param out 输出流
     * @throws IOException
     */
    public static void generateWord(File file,
                                    @Nullable Configure configure,
                                    Map<String, Object> dataMap,
                                    OutputStream out) throws IOException {
        // 初始化配置
        if (configure == null){
            configure = initConfig();
        }
        // 编译模板
        XWPFTemplate xwpfTemplate = compileTemplate(file, configure);
        // 填充数据
        fillData(xwpfTemplate, dataMap);
        // 输出数据
        outputWord(xwpfTemplate, out);
    }
}
